﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.XLANGs.BaseTypes;
using System.Diagnostics;
using Software41.Tracking.Tracing;

namespace Software41.Tracking.BAM
{
    [Serializable]
    public class ActionInfo : InfoBase
    {

        internal const string ACTIONINFO_ACTIVITY_DATA_TYPE = "Type";


        public string ActionInfoId { get { return this.InfoId; } }
        public string ParentStepInfoId { get { return this.ParentInfoId; } }


        public ActionInfo(string name, string actionInfoId, string parentStepId, IEventStream eventStream)
        {
            this.Name = name;
            this.InfoId = actionInfoId;
            this.ParentInfoId = parentStepId;
            this.EventStream = eventStream;
            this.CurrentActivityType = ActivityType.ActionInfo;
            this.ParentActivityType = ActivityType.StepInfo;
        }

        public ActionInfo(string name, string actionInfoId, string parentStepId) :
            this(name, actionInfoId, parentStepId, new Adapters.OrchestrationEventStreamAdapter())
        {
        }

        public ActionInfo(string name, string parentStepInfoId, IEventStream eventStream)
            : this(name, null, parentStepInfoId, eventStream)
        {
        }

        public ActionInfo(string name, string parentStepInfoId)
            : this(name, null, parentStepInfoId)
        {
        }

        /// <summary>
        /// This constructor should ONLY be used we Updating/Ending an already started ActionInfo
        /// </summary>
        /// <param name="actionInfoId"></param>
        /// <param name="eventStream"></param>
        public ActionInfo(string actionInfoId, IEventStream eventStream)
            : this(null, actionInfoId, null, eventStream)
        {
            this.State = ActivityStateType.Started;
        }


        /// <summary>
        /// This constructor should ONLY be used we Updating/Ending an already started ActionInfo
        /// </summary>
        /// <param name="actionInfoId"></param>
        /// <param name="eventStream"></param>
        public ActionInfo(string actionInfoId)
            : this(null, actionInfoId, null as string)
        {
            this.State = ActivityStateType.Started;
        }


        #region ExceptionInfo Mgmt

        public override void AddException(Exception ex)
        {
            base.AddException(ex);
            this.ExceptionDetail.Begin(this);
        }

        #endregion

        #region AddDetail Mgmt
        public override LogDetail AddLogDetail()
        {
            var detailInfo = base.AddLogDetail();
            detailInfo.Begin(this);

            return detailInfo;
        }

        #endregion

        #region Set Individual Field Methods
        public void SetType(string type)
        {
            this.UpdateActivity(ACTIONINFO_ACTIVITY_DATA_TYPE, type);
        }

        #endregion


        #region Private Helpers
        //private void UpdateActivity(string itemName, object itemValue)
        //{
        //    this.EventStream.UpdateActivity(ACTIONINFO_ACTIVITY, this.ActionInfoId, itemName, itemValue);
        //    this.TraceUpdateActivity(itemName, itemValue);
        //}


        //private void AddRelatedDocument(string messageDataName, string messageData, string referenceName)
        //{
        //    if ((!string.IsNullOrEmpty(messageDataName)) && (!string.IsNullOrEmpty(messageData)))
        //    {
        //        this.EventStream.AddReference(ACTIONINFO_ACTIVITY, this.ActionInfoId,
        //                                    ACTIONINFO_ACTIVITY_DATA + "-" + referenceName, referenceName,
        //                                    messageDataName, messageData);


        //        var msgDataLink = BAMLinkedDocUrlGenerator.GenerateLinkedDocUrl(ACTIONINFO_ACTIVITY, this.ActionInfoId, ACTIONINFO_ACTIVITY_DATA + "-" + referenceName);

        //        this.EventStream.AddReference(ACTIONINFO_ACTIVITY, this.ActionInfoId,
        //                                        BAMLinkedDocUrlGenerator.BAM_DOCUMENT_URL,
        //                                        messageDataName + " " + referenceName, msgDataLink);

        //    }
        //}

        internal override void TraceBeginEvent(string messageDataName, string messageData)
        {
            WorkflowProcessTraceSource.TraceEvent(TraceEventType.Information, ProcessDiagnosticsEventId.ActionInfoStart,
                                    string.Format("Begin ActionInfo Event.  ActionInfoName: [{0}]", this.Name));

            WorkflowProcessTraceSource.TraceEvent(TraceEventType.Verbose, ProcessDiagnosticsEventId.ActionInfoStart,
                            string.Format("Begin ActionInfo Event.  ActionInfoName: [{0}], " +
                                                "StepInputName: [{1}], StepInputData[{2}]",
                                                this.Name, messageDataName, messageData));
        }


        internal override void TraceEndEvent(bool successful, string messageDataName, string messageData)
        {
            WorkflowProcessTraceSource.TraceEvent(TraceEventType.Information, ProcessDiagnosticsEventId.ActionInfoEnd,
                                    string.Format("End ActionInfo Event.  ActionInfoName: [{0}], Success: [{1}]",
                                    this.Name, successful));

            WorkflowProcessTraceSource.TraceEvent(TraceEventType.Verbose, ProcessDiagnosticsEventId.ActionInfoEnd,
                            string.Format("End ActionInfo Event.  ActionInfoName: [{0}], Success: [{1}], " +
                                                "StepOutputName: [{2}], StepOutputData: [{3}]",
                                                this.Name, successful, messageDataName, messageData));
        }


        internal override void TraceUpdateActivity(string itemName, object itemValue)
        {
            WorkflowProcessTraceSource.TraceEvent(TraceEventType.Information, ProcessDiagnosticsEventId.ActivityUpdated,
                                    string.Format("ActionInfo Update Activity.  ActionInfo.{0} Value: [{1}]", itemName, itemValue));
        }

        #endregion


    }
}
